package com.ccrfid.rmc6.resource.sys;

import com.ccrfid.rmc6.appconfig.auth.Secured;
import com.ccrfid.rmc6.appconfig.exception.pojo.AppException;
import com.ccrfid.rmc6.appconfig.exception.pojo.CustomErrors;
import com.ccrfid.rmc6.entity.sys.AccountEntity;
import com.ccrfid.rmc6.entity.sys.AccountView;
import com.ccrfid.rmc6.entity.sys.RoleEntity;
import com.ccrfid.rmc6.pojo.dto.sys.AccountDto;
import com.ccrfid.rmc6.pojo.param.PageParam;
import com.ccrfid.rmc6.repository.search.Criterion;
import com.ccrfid.rmc6.repository.search.SearchCriteria;
import com.ccrfid.rmc6.resource.auth.pojo.UserPrincipal;
import com.ccrfid.rmc6.service.sys.AccountService;
import com.ccrfid.rmc6.service.sys.OrgService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;

import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import java.util.List;

@Secured
@Path("accounts")
@Produces(MediaType.APPLICATION_JSON)
public class AccountResource {
    private static final Logger logger = LoggerFactory.getLogger(AccountResource.class);
    @Context
    private SecurityContext securityContext;
    @Autowired
    private AccountService accountService;
    @Autowired
    private OrgService orgService;

    @GET
    @Path("search")
    public Page<AccountView> getAccountInfoPage(@QueryParam("userAccount") String userAccount,
                                                @QueryParam("userName") String userName,
                                                @QueryParam("orgId") Long orgId,
                                                @QueryParam("roleNames") String roleNames,
                                                @BeanParam PageParam pageParam) {
        SearchCriteria criteria = SearchCriteria.Builder.create();
        UserPrincipal userPrincipal = (UserPrincipal) securityContext.getUserPrincipal();
        orgId = userPrincipal.getOrgId();
        if (userAccount != null) {
            criteria.add(new Criterion("userAccount", Criterion.Operator.LIKE, '%' + userAccount + '%'));
        }
        if (userName != null) {
            criteria.add(new Criterion("userName", Criterion.Operator.LIKE, '%' + userName + '%'));
        }
        if (orgId != null) {
            List<Long> idList = orgService.getSubOrgIdList(orgId);
            criteria.add(new Criterion("orgId", Criterion.Operator.IN, idList));
        }
        if (roleNames != null) {
            criteria.add(new Criterion("roleNames", Criterion.Operator.LIKE, '%' + roleNames + '%'));
        }
        PageRequest pageRequest;
        if (pageParam.getOrders() != null && pageParam.getOrders().size() > 0) {
            pageRequest = PageRequest.of(pageParam.getPageNumber(), pageParam.getPageSize(), Sort.by(pageParam.getOrders()));
        } else {
            pageRequest = PageRequest.of(pageParam.getPageNumber(), pageParam.getPageSize());
        }
        Page<AccountView> page = accountService.getAccountInfoPage(criteria, pageRequest);
        return page;
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public AccountEntity createAccount(AccountEntity entity) throws AppException {
        AccountEntity accountEntity = accountService.createAccount(entity);
        return accountEntity;
    }

    @DELETE
    @Consumes(MediaType.APPLICATION_JSON)
    public int deleteAccounts(List<Long> idList) throws AppException {
        if (idList == null) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.param_is_null.getCode(), CustomErrors.param_is_null.getReason(), "");
        }
        return accountService.deleteAccounts(idList);
    }

    @GET
    @Path("{id}")
    public AccountDto getAccountInfo(@PathParam("id") Long accountId) {
        AccountDto accountDto = accountService.getAccountInfo(accountId);
        return accountDto;
    }

    @PUT
    @Path("{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    public AccountEntity updateAccount(@PathParam("id") Long accountId, AccountEntity entity) throws AppException {
        AccountEntity accountEntity = accountService.updateAccount(accountId, entity);
        return accountEntity;
    }

    @PUT
    @Path("{id}/password")
    @Consumes(MediaType.APPLICATION_JSON)
    public Boolean resetAccountPassword(@PathParam("id") Long accountId, AccountEntity entity) throws AppException {
        UserPrincipal userPrincipal = (UserPrincipal) securityContext.getUserPrincipal();
        //内置管理员只允许自己修改自己的密码
        if (!userPrincipal.getUserId().equals(1L) && accountId.equals(1L)) {
            return true;
        }
        String password = entity.getUserPasswd();
        return accountService.resetAccountPassword(accountId, password);
    }

    @GET
    @Path("{id}/roles")
    public List<RoleEntity> getRoleList(@PathParam("id") Long accountId) {
        List<RoleEntity> roleList = accountService.getRoleList(accountId);
        return roleList;
    }

    @PUT
    @Path("{id}/roles")
    @Consumes(MediaType.APPLICATION_JSON)
    public List<RoleEntity> updateRoleList(@PathParam("id") Long accountId, List<Long> roleIdList) throws AppException {
        List<RoleEntity> roleList = accountService.updateRoleList(accountId, roleIdList);
        return roleList;
    }
}
